package itheima.controller;

import itheima.domain.Card;

import java.io.*;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;

public class MetroController {
    private Scanner sc = new Scanner(System.in);

    public void start() throws IOException, ClassNotFoundException {
        while (true){
            System.out.println("--------欢迎来到合肥地铁一号线--------");
            System.out.print("请输入您的选择："+"   ");
            System.out.print("1.乘坐地铁"+"   ");
            System.out.print("2.办理地铁卡"+"   ");
            System.out.print("3.充值地铁卡"+"   ");
            System.out.println("4.退出系统");
            String choice = sc.next();
            switch (choice){
                case "1":
                    buyTicket();
                    break;
                case "2":
                    //办理地铁卡
                    registerCard();
                    break;
                case "3":
                    //充值地铁卡
                    recharge();
                    break;
                case "4":
                    System.exit(0);
                default:
                    System.out.println("您的输入有误，请重新输入");
                    break;
            }
        }
    }

    private void recharge() throws IOException {
        System.out.println("请输入您的卡号");
        String cardId;
        while (true){
            cardId = sc.next();
            //判断卡号是否有误
            boolean flag = judgeId(cardId);
            if(!flag){
                System.out.println("您的输入有误，请重新输入");
                continue;
            }

            //3.4判断卡号是否已存在
            Socket socket = new Socket("127.0.0.1",10002);
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String s = "ID_FIND&"+cardId;
            bw.write(s);
            bw.newLine();
            bw.flush();
            socket.shutdownOutput();

            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String existStr = br.readLine();//返回“true”或"false"
            flag = Boolean.parseBoolean(existStr);
            //释放
            bw.close();
            br.close();
            socket.close();

            if(flag){
                break;
            }else {
                System.out.println("卡号不存在，请重新输入");
            }
        }

        //验证
        System.out.println("请输入您的姓");
        String x = sc.next();
        Socket socket2 = new Socket("127.0.0.1",10002);
        BufferedWriter bw2 = new BufferedWriter(new OutputStreamWriter(socket2.getOutputStream()));
        String data2 = "VERIFY_USER&"+cardId+","+x;
        bw2.write(data2);
        bw2.newLine();
        bw2.flush();
        socket2.shutdownOutput();

        BufferedReader br2 = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
        String flagStr = br2.readLine();
        boolean flag = Boolean.parseBoolean(flagStr);
            //释放
        br2.close();
        bw2.close();
        socket2.close();

        if(!flag){
            System.out.println("输入错误");
            return;
        }

        //输入正确，获取用户姓名和余额
        Socket socket3 = new Socket("127.0.0.1",10002);
        BufferedWriter bw3 = new BufferedWriter(new OutputStreamWriter(socket3.getOutputStream()));
        String data3 = "GET_USERNAME_MONEY&"+cardId;
        bw3.write(data3);
        bw3.newLine();
        bw3.flush();
        socket3.shutdownOutput();

        BufferedReader br3 = new BufferedReader(new InputStreamReader(socket3.getInputStream()));
        String reDate3 = br3.readLine();
            //释放
        br3.close();
        bw3.close();
        socket3.close();

            //获取金额
        String username = reDate3.split(",")[0];
        String moneyStr = reDate3.split(",")[1];
        double money = Double.parseDouble(moneyStr);
        System.out.println("您好，"+username+"您目前的金额为："+money);

        //充值
        double charge;
        loop:
        while (true) {
            System.out.println("请输入您需要充值的金额（最低30元）");
            charge = judgeMoney();
            if(charge < 30){
                System.out.println("充值金额过低，是否退出充值（Y/N）");
                String str = sc.next();
                switch (str){
                    case "Y":
                        return;
                    case "N":
                        continue;
                    default:
                        System.out.println("您的输入有误，请重新输入：");
                        break;
                }
            }else {
                break;
            }
        }

        //记录并输出
        money += charge;
        Socket socket4 = new Socket("127.0.0.1",10002);
        BufferedWriter bw4 = new BufferedWriter(new OutputStreamWriter(socket4.getOutputStream()));
        String data4 = "CHARGE_MONEY&"+cardId+","+money;
        bw4.write(data4);
        bw4.newLine();
        bw4.flush();
        socket4.shutdownOutput();

        BufferedReader br4 = new BufferedReader(new InputStreamReader(socket4.getInputStream()));
        String flagStr2 = br4.readLine();
        boolean flag2 = Boolean.parseBoolean(flagStr2);
            //释放
        br4.close();
        bw4.close();
        socket4.close();

        if(flag2){
            System.out.println("充值成功，目前"+username+"您的余额为"+money);
        }
    }

    private void registerCard() throws IOException {
        //1.确认是否注册
        System.out.println("请确认是否注册：Y/N");
        loop1:
        while (true) {
            String input = sc.next();
            switch (input){
                case "Y":
                    //注册
                    break loop1;
                case "N":
                    //取消注册
                    System.out.println("您取消了注册");
                    return;
                default:
                    System.out.println("您的输入有误，请重新输入");
                    break;
            }
        }

        //2.输入姓名
        System.out.println("请输入您的姓名：");
        String username = sc.next();

        //3.输入卡号
        String cardId;
        System.out.println("请输入您的卡号（5位字符串，首字母必须是小写字母，后四位必须是数字）：");
        while (true) {
            cardId = sc.next();
            boolean flag = judgeId(cardId);
            if(!flag){
                System.out.println("您的输入有误，请重新输入");
                continue;
            }

            //3.4判断卡号是否已存在
            Socket socket = new Socket("127.0.0.1",10002);
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String s = "ID_FIND&"+cardId;
            bw.write(s);
            bw.newLine();
            bw.flush();
            socket.shutdownOutput();

            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String existStr = br.readLine();//返回“true”或"false"
            flag = Boolean.parseBoolean(existStr);
                //释放
            bw.close();
            br.close();
            socket.close();

            if(!flag) {
                break;
            }else {
                System.out.println("卡号已存在，请重新输入");
            }

        }

        //4.充值
        System.out.println("请输入您需要充值的余额(最低30元)：");
        double money;
        while (true) {
            money = judgeMoney();
            if(money < 30){
                System.out.println("充值金额过低，请重新输入");
            }else {
                break;
            }
        }

        //5.创建卡号
        Card card = new Card(username,cardId,money);
            //向服务器传输充值后的卡号信息；
        Socket socket = new Socket("127.0.0.1",10002);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        String data = "ADD_USER&"+card.toString();
        bw.write(data);
        bw.newLine();
        bw.flush();
        socket.shutdownOutput();
            //获得服务器返回结果
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String clientFlag = br.readLine();
            //释放
        br.close();
        bw.close();
        socket.close();

        boolean flag = Boolean.parseBoolean(clientFlag);

        if(flag){
            Socket sk = new Socket("127.0.0.1",10002);
            BufferedWriter bw1 = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
            String data1 = "GET_USERNAME&"+cardId;
            bw1.write(data1);
            bw1.newLine();
            bw1.flush();
            sk.shutdownOutput();
                //获得服务器返回结果
            BufferedReader br1 = new BufferedReader(new InputStreamReader(sk.getInputStream()));
            String un = br1.readLine();
            System.out.println("注册成功，请保存好您的卡号信息：姓名"+un+"，卡号"+cardId+"，余额："+money);
                //释放
            br1.close();
            bw1.close();
            sk.close();
        }
    }

    private double judgeMoney() {
        double money = 0.0;
        while (true) {
            try {
                //4.1输入金额
                String moneyStr = sc.next();
                money = Double.parseDouble(moneyStr);
            } catch (NumberFormatException e) {
                //若内容非法则重新输入
                System.out.println("输入非法内容，请输入正确金额：");
                continue;
            }
            break;
        }
        return money;
    }

    private boolean judgeId(String cardId){
        char [] chr = cardId.toCharArray();
        //3.1字符串长度为5
        if(chr.length != 5){
            return false;
        }
        //3.2首字母必须为小写字母
        if(chr[0] < 'a' || chr[0] > 'z'){
            return false;
        }
        //3.3后四位必须是数字
        for (int i = 1; i < chr.length; i++) {
            if(chr[i] < '0' || chr[i] > '9'){
                return false;
            }
        }
        return true;
    }

    private void buyTicket() throws IOException, ClassNotFoundException {
        /*
        1.获得地铁站并打印
         */
            //1.1向服务器发送请求获取车站
        Socket socket1 = new Socket("127.0.0.1",10002);
        BufferedWriter bw1 = new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream()));
        String station = "GET_STATIONS&"+"STATIONS";
        bw1.write(station);
        bw1.newLine();
        bw1.flush();
        socket1.shutdownOutput();


            //2.获得服务器返回的车站
        ObjectInputStream ois = new ObjectInputStream(socket1.getInputStream());
        ArrayList<String> stations = (ArrayList<String>) ois.readObject();
        ois.close();
        bw1.close();
        socket1.close();

        loop:
        while (true) {
            System.out.println("--------欢迎来到合肥地铁一号线--------");
            System.out.println("车站列表如下");
            System.out.println(stations);

        /*
        2.输入上车站和下车站
         */
            System.out.println("请输入您的上车站：");
            String startStation;
            while (true) {
                startStation = sc.next();
                boolean flag = judgeStation(startStation,stations);
                if(flag){
                    break;
                }else {
                    if(startStation.equals("-1")){
                        return;
                    }
                    System.out.println("您输入的上车站不存在，请重新输入:");
                }
            }

            System.out.println("请输入您的下车站：");
            String endStation;
            while (true) {
                endStation = sc.next();
                boolean flag = judgeStation(endStation,stations);
                if(flag){
                    break;
                }else {
                    System.out.println("您输入的下车站不存在，请重新输入:");
                }
            }

        /*
        3.输入交通卡号
        若存在：记录并放行；
        不存在：提示是否注册；
         */
            loop1:
            while (true) {
                System.out.println("请输入您的交通卡号（首字母小写+4位数字）");
                String cardId = sc.next();
                boolean flag = judgeId(cardId);
                if(!flag){
                    System.out.println("卡号格式不正确，请重新输入");
                    continue;
                }
                //3.4判断卡号是否已存在
                Socket socket2 = new Socket("127.0.0.1",10002);
                BufferedWriter bw2 = new BufferedWriter(new OutputStreamWriter(socket2.getOutputStream()));
                String s = "ID_FIND&"+cardId;
                bw2.write(s);
                bw2.newLine();
                bw2.flush();
                socket2.shutdownOutput();

                BufferedReader br2 = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
                String existStr = br2.readLine();//返回“true”或"false"
                boolean flag2 = Boolean.parseBoolean(existStr);

                br2.close();
                bw2.close();
                socket2.close();
                if(!flag2){
                    while (true) {
                        System.out.print("卡号不存在，请选择："+"\t");
                        System.out.print("1.注册新用户"+"\t");
                        System.out.println("2.重新输入");
                        String str = sc.next();
                        switch (str){
                            case "1":
                                //注册新用户
                                registerCard();
                                break loop1;
                            case "2":
                                continue loop1;
                                //重新输入
                            default:
                                System.out.println("您的输入有误，请重新输入：");
                                break;
                        }
                    }
                }else {
                    String data = "BUY_TICKET&"+cardId+","+startStation+","+endStation;
                    //向服务器传输购票记录
                    Socket sk = new Socket("127.0.0.1",10002);
                    BufferedWriter bw3 = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
                    bw3.write(data);
                    bw3.newLine();
                    bw3.flush();
                    sk.shutdownOutput();

                    BufferedReader br3 = new BufferedReader(new InputStreamReader(sk.getInputStream()));
                    String userMessage = br3.readLine();
                    String username = userMessage.split("&")[0];
                    String message = userMessage.split("&")[1];

                    //释放
                    br3.close();
                    bw3.close();
                    sk.close();

                    if(message.equals("ERROR_WRONGSTATION")){
                        System.out.println("系统错误，请稍后再试");
                    }else if(message.equals("ERROR_NOTSUFFICIENTFUND")){
                        System.out.println("您的金额不足，请充值后再试");
                    }else {
                        SimpleDateFormat sdf = new SimpleDateFormat("<yyyy-MM-dd HH:mm:ss>");
                        long time = System.currentTimeMillis();
                        Date date = new Date(time);
                        String currentTime = sdf.format(date);

                        String log = "SAVE_USERLOG&"+currentTime+","+cardId+","+startStation+","+endStation;
                        Socket socket4 = new Socket("127.0.0.1",10002);
                        BufferedWriter bw4 = new BufferedWriter(new OutputStreamWriter(socket4.getOutputStream()));
                        bw4.write(log);
                        bw4.newLine();
                        bw4.flush();
                        socket4.shutdownOutput();

                        bw4.close();
                        socket4.close();

                        String fee = message.split(",")[1];
                        String money = message.split(",")[0];
                        System.out.println(username+"购买成功，票价为："+fee+"，您的余额为："+money);
                    }
                    break loop;
                }
            }
        }
    }

    private boolean judgeStation(String station,ArrayList<String> stations){
        for (String s : stations) {
            if (s.equals(station)) {
                return true;
            }
        }
        return false;
    }
}
